﻿using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Web.Security;

namespace LB.Common
{
    [ServiceContract]
    public interface IUserAdministrationService : IRemoteService
    {
        /// <summary>
        /// Login user in the system. If user has been login successfully LoginToken will be returned, else Null.
        /// </summary>
        /// <param name="login">Users login</param>
        /// <param name="hash">Hash code of the user password</param>
        /// <returns>Login Token</returns>
        [OperationContract]
        LoginToken Login(string login, string hash);

        /// <summary>
        /// Delete current Session
        /// </summary>
        /// <param name="loginToken">LoginToken of current session</param>
        [OperationContract]
        void Logout(LoginToken loginToken);

//        /// <summary>
//        /// Verify does is user logined
//        /// </summary>
//        /// <param name="loginToken">session login token</param>
//        /// <returns>bool result</returns>
//        [OperationContract]
//        bool VerifyLogin(LoginToken loginToken);
        

    #region Create

        /// <summary>
        /// Adds a new membership user to the data source.
        /// </summary>
        /// 
        /// <returns>
        /// A <see cref="T:System.Web.Security.MembershipUser"/> object populated with the information for the newly created user.
        /// </returns>
        /// <param name="username">The user name for the new user. </param><param name="password">The password for the new user. </param><param name="email">The e-mail address for the new user.</param><param name="passwordQuestion">The password question for the new user.</param><param name="passwordAnswer">The password answer for the new user</param><param name="isApproved">Whether or not the new user is approved to be validated.</param><param name="providerUserKey">The unique identifier from the membership data source for the user.</param><param name="status">A <see cref="T:System.Web.Security.MembershipCreateStatus"/> enumeration value indicating whether the user was created successfully.</param>
        [OperationContract]
        MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status);

        /// <summary>
        /// When overridden in a derived class, creates a new OAuth membership account, or updates an existing OAuth Membership account.
        /// </summary>
        /// <param name="provider">The OAuth or OpenID provider.</param><param name="providerUserId">The OAuth or OpenID provider user ID. This is not the user ID of the user account, but the user ID on the OAuth or Open ID provider.</param><param name="userName">The user name.</param>
        [OperationContract]
        void CreateOrUpdateOAuthAccount(string provider, string providerUserId, string userName);

        /// <summary>
        /// When overridden in a derived class, creates a new user profile and a new membership account.
        /// </summary>
        /// 
        /// <returns>
        /// A token that can be sent to the user to confirm the user account.
        /// </returns>
        /// <param name="userName">The user name.</param><param name="password">The password.</param><param name="requireConfirmation">(Optional) true to specify that the user account must be confirmed; otherwise, false. The default is false.</param><param name="values">(Optional) A dictionary that contains additional user attributes to store in the user profile. The default is null.</param>
        [OperationContract]
        string CreateUserAndAccount(string userName, string password, bool requireConfirmation, IDictionary<string, object> values);
        
        /// <summary>
        /// Activates a pending membership account for the specified user.
        /// </summary>
        /// 
        /// <returns>
        /// true if the account is confirmed; otherwise, false.
        /// </returns>
        /// <param name="userName">The user name.</param><param name="accountConfirmationToken">A confirmation token to pass to the authentication provider.</param>
        [OperationContract]
        bool ConfirmAccount(string userName, string accountConfirmationToken);
    #endregion

    #region Read
        /// <summary>
        /// Return User Info about current user
        /// </summary>
        /// <param name="loginToken">LoginToken loginToken of current session</param>
        /// <returns>User Info</returns>
        [OperationContract]
        User GetCurrentUserInfo(LoginToken loginToken);

        /// <summary>
        /// Verifies that the specified user name and password exist in the data source.
        /// </summary>
        /// 
        /// <returns>
        /// true if the specified username and password are valid; otherwise, false.
        /// </returns>
        /// <param name="username">The name of the user to validate. </param><param name="password">The password for the specified user. </param>
        [OperationContract]
        bool ValidateUser(string username, string password);

        /// <summary>
        /// Gets user information from the data source based on the unique identifier for the membership user. Provides an option to update the last-activity date/time stamp for the user.
        /// </summary>
        /// 
        /// <returns>
        /// A <see cref="T:System.Web.Security.MembershipUser"/> object populated with the specified user's information from the data source.
        /// </returns>
        /// <param name="providerUserKey">The unique identifier for the membership user to get information for.</param><param name="userIsOnline">true to update the last-activity date/time stamp for the user; false to return user information without updating the last-activity date/time stamp for the user.</param>
        [OperationContract]
        MembershipUser GetUser(object providerUserKey, bool userIsOnline);

        /// <summary>
        /// Gets information from the data source for a user. Provides an option to update the last-activity date/time stamp for the user.
        /// </summary>
        /// 
        /// <returns>
        /// A <see cref="T:System.Web.Security.MembershipUser"/> object populated with the specified user's information from the data source.
        /// </returns>
        /// <param name="username">The name of the user to get information for. </param><param name="userIsOnline">true to update the last-activity date/time stamp for the user; false to return user information without updating the last-activity date/time stamp for the user. </param>
        [OperationContract]
        MembershipUser GetUser(string username, bool userIsOnline);

        /// <summary>
        /// Gets the user name associated with the specified e-mail address.
        /// </summary>
        /// 
        /// <returns>
        /// The user name associated with the specified e-mail address. If no match is found, return null.
        /// </returns>
        /// <param name="email">The e-mail address to search for. </param>
        [OperationContract]
        string GetUserNameByEmail(string email);

        /// <summary>
        /// When overridden in a derived class, returns the user ID for the specified OAuth or OpenID provider and provider user ID.
        /// </summary>
        /// <param name="provider">The name of the OAuth or OpenID provider.</param><param name="providerUserId">The OAuth or OpenID provider user ID. This is not the user ID of the user account, but the user ID on the OAuth or Open ID provider.</param>
        [OperationContract]
        int GetUserIdFromOAuth(string provider, string providerUserId);

        /// <summary>
        /// Returns the user name that is associated with the specified user ID.
        /// </summary>
        /// 
        /// <returns>
        /// The user name.
        /// </returns>
        /// <param name="userId">The user ID to get the name for.</param>
        [OperationContract]
        string GetUserNameFromId(int userId);
        
        /// <summary>
        /// When overridden in a derived class, generates a password reset token that can be sent to a user in email.
        /// </summary>
        /// 
        /// <returns>
        /// A token to send to the user.
        /// </returns>
        /// <param name="userName">The user name.</param><param name="tokenExpirationInMinutesFromNow">(Optional) The time, in minutes, until the password reset token expires. The default is 1440 (24 hours).</param>
        [OperationContract]
        string GeneratePasswordResetToken(string userName, int tokenExpirationInMinutesFromNow);

        /// <summary>
        /// When overridden in a derived class, returns the number of times that the password for the specified user account was incorrectly entered since the most recent successful login or since the user account was created.
        /// </summary>
        /// 
        /// <returns>
        /// The count of failed password attempts for the specified user account.
        /// </returns>
        /// <param name="userName">The user name of the account.</param>
        [OperationContract]
        int GetPasswordFailuresSinceLastSuccess(string userName);

        /// <summary>
        /// When overridden in a derived class, returns all OAuth membership accounts associated with the specified user name.
        /// </summary>
        /// 
        /// <returns>
        /// A list of all pairs of ProviderId and ProviderUserId membership accounts associated with the specified user name.
        /// </returns>
        /// <param name="userName">The user name.</param>
        [OperationContract]
        ICollection<Tuple<string, string>> GetAccountsForUser(string userName);
        #endregion

    #region Update
        /// <summary>
        /// Processes a request to update the password for a membership user.
        /// </summary>
        /// 
        /// <returns>
        /// true if the password was updated successfully; otherwise, false.
        /// </returns>
        /// <param name="username">The user to update the password for. </param><param name="oldPassword">The current password for the specified user. </param><param name="newPassword">The new password for the specified user. </param>
        [OperationContract]
        bool ChangePassword(string username, string oldPassword, string newPassword);

        /// <summary>
        /// Resets a user's password to a new, automatically generated password.
        /// </summary>
        /// 
        /// <returns>
        /// The new password for the specified user.
        /// </returns>
        /// <param name="username">The user to reset the password for. </param><param name="answer">The password answer for the specified user. </param>
        [OperationContract]
        string ResetPassword(string username, string answer);

        /// <summary>
        /// Updates information about a user in the data source.
        /// </summary>
        /// <param name="user">A <see cref="T:System.Web.Security.MembershipUser"/> object that represents the user to update and the updated information for the user. </param>
        [OperationContract]
        void UpdateUser(MembershipUser user);

        /// <summary>
        /// Clears a lock so that the membership user can be validated.
        /// </summary>
        /// 
        /// <returns>
        /// true if the membership user was successfully unlocked; otherwise, false.
        /// </returns>
        /// <param name="userName">The membership user whose lock status you want to clear.</param>
        [OperationContract]
        bool UnlockUser(string userName);

        [OperationContract]
        void StoreOAuthRequestToken(string requestToken, string requestTokenSecret);

        [OperationContract]
        void ReplaceOAuthRequestTokenWithAccessToken(string requestToken, string accessToken, string accessTokenSecret);
    #endregion

    #region Delete
        
        /// <summary>
        /// Removes a user from the membership data source.
        /// </summary>
        /// 
        /// <returns>
        /// true if the user was successfully deleted; otherwise, false.
        /// </returns>
        /// <param name="username">The name of the user to delete.</param><param name="deleteAllRelatedData">true to delete data related to the user from the database; false to leave data related to the user in the database.</param>
        [OperationContract]
        bool DeleteUser(string username, bool deleteAllRelatedData);

        /// <summary>
        /// When overridden in a derived class, deletes the OAuth or OpenID account with the specified provider name and provider user ID.
        /// </summary>
        /// <param name="provider">The name of the OAuth or OpenID provider.</param><param name="providerUserId">The OAuth or OpenID provider user ID. This is not the user ID of the user account, but the user ID on the OAuth or Open ID provider.</param>
        [OperationContract]
        void DeleteOAuthAccount(string provider, string providerUserId);

        //void DeleteOAuthToken(string token);
    #endregion
    }
}
